//
//	File: Script.h
//
// This class is used to read string scripts.
// Such scripts are used for materials description

#ifndef OY_MATERIALSCRIPT_H
#define OY_MATERIALSCRIPT_H
#include <windows.h>
#include "../../OyMath3D/OyMath3D.h"
#include "../../OyGeneral/OyGeneral.h"
#include "../DataStruct/OyDataStruct.h"


class Script
{
public :
	// public structures
	class Section
	{
	public :
		// ctor(s) & dtor
		~Section();

		// public types
		typedef OyArrayStack<Section*>		SectionList;
		typedef OyArrayStack<const char*>	StackName;

		// public interface

		int				ContainSection( const char* id );
		Section*		GetSection( const char* name, int ID = 0 );
		bool			ContainBool   ( const char* id );
		bool			GetBool( const char* id, bool def = false );
		bool			ContainString ( const char* id );
		const char*		GetString( const char* id, const char* def = "" );
		int				GetInt( const char* id, int def = 0 );
		OyVector4D		GetVec4( const char* id, const OyVector4D & def = OyVector4D(0, 0, 0) );


		float GetFloat( const char* id, float def = 0.f );

		
		static const int INIT_MATERIALSECTION_STACK_NUM	= 8;
		static const int INIT_MATERIALVALUE_STACK_NUM = 64;

	private :
		// ctor(s) & dtor
		Section();
		Section( char* MaterialStr );

		// private types
		StackName		LineID_;
		StackName		LineValue_;

		SectionList		sections_;
		StackName		names_;

		// private helper structures
		struct BuildInfo
		{
			inline BuildInfo( char* MaterialStr, bool global )
				: Material_Str( MaterialStr ), global( global )
			{
			}

			char* Material_Str;
			bool global;
		};

		// private helper functions
		void LoadFromMaterialStr( BuildInfo & buildInfo );
		void ReadSection( BuildInfo & buildInfo, char* id );
		void ReadValue( BuildInfo & buildInfo, char* line, int index );
		static bool IsAlphaNumeric( char c );
		static bool GetLine( BuildInfo & buildInfo, char** line );

		// friendship
		friend class Script;
	};


	// ctor(s) & dtor
	Script( char* MaterialStr );
	~Script();

	// public interface


	inline int GetInt( const char* id, int def = 0 ) { return global_->GetInt( id, def ); }
	inline float GetFloat( const char* id, float def = 0.f ) { return global_->GetFloat( id, def ); }
	inline OyVector4D GetVec4( const  char* id, const OyVector4D & def = OyVector4D(0, 0, 0) ) { return global_->GetVec4( id, def ); }

	inline int			ContainSection( const char* id ) { return global_->ContainSection( id ); }
	inline Script::Section* GetSection( const char* name, int ID = 0  ) { return global_->GetSection( name, ID ); }
	inline bool			ContainBool   ( const char* id ) { return global_->ContainBool( id ); }
	inline bool			GetBool( const char* id, bool def = false ) { return global_->GetBool( id, def ); }
	inline bool			ContainString ( const char* id ) { return global_->ContainString( id ); }
	inline const char*	GetString( const char* id, const char* def = "" ) { return global_->GetString( id, def ); }

private :
	Script::Section * global_;
};



#endif
